﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Castle.Core.Resource;
using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;

namespace N2.Explorer
{
	using N2.Explorer.Services;
	using Properties;
	
	class ConfigurationService
	{
		static SessionSettings s_settings;

		public static SessionSettings SessionSettings {
			get { return s_settings ?? (s_settings = new SessionSettings()); }
		}
		
		static ConfigureSessionDialog s_dialog;
		
		static ConfigureSessionDialog Dialog {
			get { return s_dialog
				?? (s_dialog = new ConfigureSessionDialog());
			}
		}

		public static bool LetUserReconfigureSession()
		{
			bool _result = false;
			
			SessionSettings.ConfigurationFile = Properties.Settings.Default.ConfigurationFile;
			SessionSettings.AssemblyNameList.Clear();
			SessionSettings.AssemblyFileNames = Settings.Default.Assemblies.Cast<string>();

			do {
				_result = LetUserUpdateConfiguration();

				if (!_result) {
					return false;
				}
			
			} while (string.IsNullOrEmpty(SessionSettings.ConfigurationFile));

			Settings.Default.ConfigurationFile = SessionSettings.ConfigurationFile;
			Settings.Default.Assemblies.Clear();
			Settings.Default.Assemblies.AddRange(SessionSettings.AssemblyFileNames.ToArray());
			
			Settings.Default.Save();

			ApplyConfiguration(SessionSettings);
			
			return true;
		}

		static bool LetUserUpdateConfiguration()
		{
			Dialog.pg.SelectedObject = new SettingsFacade(SessionSettings);
			return Dialog.ShowDialog() == DialogResult.OK;
		}

		public static void ApplyConfiguration(SessionSettings configuration)
		{
			new N2Launcher(configuration).Initialize();
			
			new Dictionary<string, Type> {
				{ "TypeDescriptorService", typeof(TypeDescriptorService) },
				{ "IconService", typeof(IconService)},
				{ "ViewService", typeof(ViewService) },
			}.Where(_kvp => null == Container.GetService(_kvp.Value))
			.ToList()
			.ForEach(_kvp => Container.AddComponent(_kvp.Key, _kvp.Value));
		}
	
		static IWindsorContainer CreateContainer()
		{
			return new WindsorContainer(
				new XmlInterpreter(
					new ConfigResource("castle")));
		}

		static IWindsorContainer m_container;
		public static IWindsorContainer Container {
			get {
				return m_container
					?? (m_container = CreateContainer());
			}
		}
	}
}
